﻿using System.Collections.Generic;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;

public class LobbyManager : NetworkBehaviour
{
    [SerializeField] Transform spawnTF;
    [SerializeField] GameObject playerUIPrefab;
    [SerializeField] TMP_Text invitationCodeText;
    [SerializeField] Button exitBT;    
    //主机显示开始游戏按钮、客户端显示准备按钮
    [SerializeField] Button startGameBT;
    [SerializeField] Button readyBT;
    NetworkVariable<FixedString64Bytes> invCode;
    Dictionary<ulong, ChoosePlayerUI> players = new();

    private void Awake()
    {
        invCode = new();        
    }

    public override void OnDestroy()
    {
        invCode?.Dispose();
        base.OnDestroy();
    }

    public override void OnNetworkSpawn()
    {        
        var nm = NetworkManager.Singleton;
        var mm = MultiPlayManager.Instance;

        mm.Players.OnListChanged += OnPlayerChanged;
        if (IsHost)
        {
            startGameBT.gameObject.SetActive(true);
            Destroy(readyBT.gameObject);
            startGameBT.onClick.AddListener(OnStartGame);
            invCode.Value = ConnectionManager.GetInvitationCode();
            invitationCodeText.text = invCode.Value.ToString();
        }
        else
        {
            Destroy(startGameBT.gameObject);
            readyBT.gameObject.SetActive(true);
            readyBT.onClick.AddListener(()=>OnReadyBTClickRpc(NetworkManager.LocalClientId));
            invitationCodeText.text = invCode.Value.ToString();
        }
        foreach (var e in mm.Players)
        {            
            CreatePlayerUI(e);
        }
    }

    public override void OnNetworkDespawn()
    {
        MultiPlayManager.Instance.Players.OnListChanged -= OnPlayerChanged;
    }

    private void OnEnable()
    {       
        exitBT.onClick.AddListener(ExitLobby);
    }
    private void OnDisable()
    {        
        exitBT.onClick?.RemoveListener(ExitLobby);
    }

    [Rpc(SendTo.ClientsAndHost)]
    void OnReadyBTClickRpc(ulong id)
    {
        players[id].OnReadyBTClick();
    }

    void OnStartGame()
    {
        foreach(var e in players)
        {
            if (!e.Value.IsReady)
            {
                Debug.Log("cant start game because " + e.Key + " is not ready");
                return;
            }                
        }
        GameManager.Instance.StartMultiGame();
    }

    void ExitLobby()
    {
        Debug.Log("exitLobby");
        ConnectionManager.Instance.ShutDown();        
    }
  
    private void OnPlayerChanged(NetworkListEvent<PlayerData> changeEvent)
    {                
        switch (changeEvent.Type)
        {
            case NetworkListEvent<PlayerData>.EventType.Add:
                CreatePlayerUI(changeEvent.Value);
                break;
            case NetworkListEvent<PlayerData>.EventType.Remove:
            case NetworkListEvent<PlayerData>.EventType.RemoveAt:
                RemovePlayerUI(changeEvent.Value);
                break;
        }
    }   
    
    void CreatePlayerUI(PlayerData data)
    {        
        if (!players.ContainsKey(data.id))
        {    
            var playerUI= Instantiate(playerUIPrefab,spawnTF).GetComponent<ChoosePlayerUI>();            
            playerUI.SetData(data.name.ToString(),data.id);
            players.Add(data.id, playerUI);
        }
    }

    void RemovePlayerUI(PlayerData data)
    {        
        if (players.ContainsKey(data.id))
        {                        
            Destroy(players[data.id].gameObject);
            players.Remove(data.id);
        }
    }
}
